#include <QtCore/QSettings>
#include <QtNetwork/QNetworkConfigurationManager>
#include <QtNetwork/QNetworkSession>
#include "lineshare.h"
#include "client.h"

// Create LineShare object and initialize data structure
LineShare::LineShare(QObject *parent) : QObject(parent), m_currentStroke(){}

// Startup network connection
void LineShare::setupNetwork(){
    qDebug() << "LineShare::setupNetwork(*app)";
    QNetworkConfigurationManager manager;
    if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
        qDebug() << "  manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired";
        // Get saved network configuration
        QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
        settings.beginGroup(QLatin1String("QtNetwork"));
        const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
        settings.endGroup();

        // If the saved network configuration is not currently discovered use the system default
        QNetworkConfiguration config = manager.configurationFromIdentifier(id);
        if ((config.state() & QNetworkConfiguration::Discovered) !=
            QNetworkConfiguration::Discovered) {
            config = manager.defaultConfiguration();
        }

        QNetworkSession *networkSession = new QNetworkSession(config);
        networkSession->open();
        networkSession->waitForOpened();

        if (networkSession->isOpen()) {
            // Save the used configuration
            QNetworkConfiguration config = networkSession->configuration();
            QString id;
            if (config.type() == QNetworkConfiguration::UserChoice) {
                id = networkSession->sessionProperty(
                        QLatin1String("UserChoiceConfiguration")).toString();
            } else {
                id = config.identifier();
            }

            QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
            settings.beginGroup(QLatin1String("QtNetwork"));
            settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
            settings.endGroup();
        }
    }

    connect(&client, SIGNAL(newMessage(QString)), this, SLOT(receiveMessage(QString)));
    connect(this, SIGNAL(sendMessage(QString)), &client, SLOT(sendMessage(QString)));
    //client.sendMessage2("text");
}

// Add points to the current stroke
void LineShare::addPoint(QPoint point){
    m_currentStroke.addPoint(point);
}
void LineShare::addPoint(int x, int y){
    m_currentStroke.addPoint(x,y);
}

// Finish a stroke
void LineShare::strokeComplete(){
    QString msg = "1%";
    //[time stamp] [pen width] [pen r] [pen g] [pen b]
    msg.append(QDateTime::currentDateTime().toString());
    msg.append("%");
    msg.append(QString::number(m_currentStroke.getPenWidth()));
    msg.append("%");
    msg.append(QString::number(m_currentStroke.getR()) + "%" +
               QString::number(m_currentStroke.getG()) + "%" +
               QString::number(m_currentStroke.getB())+"%");
    //Add Points
    for(int j = 0; j<m_currentStroke.m_points.size(); j++){
       QPoint myPoint = m_currentStroke.m_points.at(j);
       int x = myPoint.x();
       int y = myPoint.y();
       msg.append(QString::number(x) + "," + QString::number(y) + ";");
    }
    if(m_currentStroke.m_points.size()>0)
            msg.chop(1);
    qDebug() << "Outgoing msg: "<< msg;
    m_commonStrokes.append(m_currentStroke);
    m_currentStroke = Stroke();
    emit sendMessage(msg);
}

// Clear the strokes vector.  Tell other clients complete
void LineShare::clear(){
    m_currentStroke = Stroke();
    m_commonStrokes = QVector<Stroke>();
    QString msg = "2%clear";
    emit sendMessage(msg);
}

// Get pen settings
int LineShare::getCurrentR(){
    return m_currentStroke.getR();
}
int LineShare::getCurrentG(){
    return m_currentStroke.getG();
}
int LineShare::getCurrentB(){
    return m_currentStroke.getB();
}
int LineShare::getCurrentPenWidth(){
    return m_currentStroke.getPenWidth();
}

// Set pen settings
void LineShare::setCurrentR(int r){
    m_currentStroke.setR(r);
}
void LineShare::setCurrentG(int g){
    m_currentStroke.setG(g);
}
void LineShare::setCurrentB(int b){
    m_currentStroke.setB(b);
}
void LineShare::setCurrentColor(int r, int g, int b){
    m_currentStroke.setR(r);
    m_currentStroke.setG(g);
    m_currentStroke.setB(b);
}
void LineShare::setCurrentColor(QColor color){
    m_currentStroke.setR(color.red());
    m_currentStroke.setG(color.green());
    m_currentStroke.setB(color.blue());
}
void LineShare::setCurrentPenWidth(int width){
    m_currentStroke.setPenWidth(width);
}

// Pass user painter
void LineShare::sharePainter(QPainter * userPainter){
    m_painter = userPainter;
}


// Draw with user painter
void LineShare::drawWithPainter(){
    QPen pen = m_painter->pen();
    pen.setCapStyle(Qt::RoundCap);
    //pen.setStyle(m_style);
   for (int i = 0; i < m_commonStrokes.size(); i++){
       Stroke stroke = m_commonStrokes.at(i);
       pen.setWidth(stroke.getPenWidth());
       pen.setColor(QColor(stroke.getR(), stroke.getG(), stroke.getB()));
       m_painter->setPen(pen);
       for(int j = 0; j<(stroke.m_points.size()-1); j++){
           m_painter->drawLine(stroke.m_points.at(j), stroke.m_points.at(j+1));
       }
   }
   Stroke stroke = m_currentStroke;
   pen.setWidth(stroke.getPenWidth());
   pen.setColor(QColor(stroke.getR(), stroke.getG(), stroke.getB()));
   m_painter->setPen(pen);
   for(int j = 0; j<(stroke.m_points.size()-1); j++){
       m_painter->drawLine(stroke.m_points.at(j), stroke.m_points.at(j+1));
   }
}

// SLOTS
//Process incoming messages here
void LineShare::receiveMessage(QString msgIn){
    qDebug() << "LineShare::receiveMessage" << msgIn;

    // Decode message
    // add to list of vectors as necessary
    QStringList list = msgIn.split("%");
    QString msgType = list.at(0);

    // Switch on msg type
    // Stroke recieved
    if(msgType.toInt() ==1){
        QString dateTime = list.at(1);
        QString penWeight = list.at(2);
        QString red = list.at(3);
        QString green = list.at(4);
        QString blue = list.at(5);
        QString points = list.at(6);
        QStringList pointList = points.split(";");
        Stroke stroke;
        for(int i=0; i<pointList.size(); i++){
            QString pointI = pointList.at(i);
            QStringList pointXY = pointList.at(i).split(",");
            int x = pointXY.at(0).toInt();
            int y = pointXY.at(1).toInt();
            stroke.addPoint(x,y);
        }
        stroke.setR(red.toInt());
        stroke.setG(green.toInt());
        stroke.setB(blue.toInt());
        stroke.setPenWidth(penWeight.toInt());
        m_commonStrokes.append(stroke);
        emit strokeReceived(stroke);
        emit repaint();
    }

    // Clear Received
    else if(msgType.toInt() ==2){
        emit clearReceived();
    }


}

